﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Xml;
using System.Data;
using System.Data.Common;
using Microsoft.Office.Interop.Word;
using RFSerchComponent;
using FrameWork.DataBaseProvider;

namespace IndexService
{
    public static class IndexCore
    {
        private static Framework.Log.ILog log = Framework.Log.LogFactory.CreateInstance();

        /// <summary>
        /// 创建索引
        /// </summary>
        public static string CreateIndex(ref int count, EnumServices service)
        {
            string indexPath = "";
            string xmlPath = "";
            string sqlUpdateAtt = "";
            string sqlUpdateNews = "";
            string sqlUpdateNewsEconomy = "";
            string sqlUpdateSMS = "";

            switch (service)
            {
                case EnumServices.REAL_TIME:
                case EnumServices.REAL_TIME_REBUILT:
                    {
                        indexPath = "RealTimeIndex";
                        xmlPath = "RealTimeXML";
                        sqlUpdateAtt = "UPDATE P_BT_Attachments SET isXML = 2, AttachmentText = '{0}'  WHERE (AttachmentID = '{1}')";
                        sqlUpdateNews = "UPDATE OA_News_Docs SET isXML = 2 WHERE (AnnoNewsID = '{0}')";
                        sqlUpdateNewsEconomy = "UPDATE OA_News_Economy SET isXML = 2 WHERE (REC_ID = '{0}')";
                        sqlUpdateSMS = "UPDATE OA_WS_InstantMessage_Docs SET isXML = 2 WHERE (SMSID = '{0}')";
                    } break;

                case EnumServices.FILE_TIME:
                case EnumServices.FILE_TIME_REBUILT:
                    {
                        indexPath = "FileTimeIndex";
                        xmlPath = "FileTimeXML";
                        sqlUpdateAtt = "UPDATE P_BT_Attachments SET isXML = 4 WHERE (AttachmentID = '{0}')";
                        sqlUpdateNews = "UPDATE OA_News_Docs SET isXML = 4 WHERE (AnnoNewsID = '{0}')";
                        sqlUpdateNewsEconomy = "UPDATE OA_News_Economy SET isXML = 4 WHERE (REC_ID = '{0}')";
                        sqlUpdateSMS = "UPDATE OA_WS_InstantMessage_Docs SET isXML = 4 WHERE (SMSID = '{0}')";
                    } break;

                default:
                    {
                        indexPath = "";
                        xmlPath = "";
                    } break;
            }

            if (indexPath == "")
            {
                log.WirteLog("创建索引失败，service名称：" + service.ToString() + "无效");
                return "";
            }

            count = 0;
            StringBuilder sb = new StringBuilder();  //构建update语句
            DirectoryInfo dir = new DirectoryInfo(ConfigurationManager.AppSettings[indexPath]);
            if (!dir.Exists)
            {
                dir.Create();
            }

            if (service == EnumServices.FILE_TIME || service == EnumServices.REAL_TIME)
            {
                RFSerchComponent.Index.CreateIndex(dir.FullName);
            }
            else if (service == EnumServices.REAL_TIME_REBUILT || service == EnumServices.FILE_TIME_REBUILT)
            {
                RFSerchComponent.Index.Rebuild(dir.FullName);
                RFSerchComponent.Index.CreateIndex(dir.FullName);
            }

            string xmlFile = ConfigurationManager.AppSettings[xmlPath] + "news.xml";

            using (FileStream fs = new FileStream(xmlFile, FileMode.Open))
            {
                XmlTextReader reader = new XmlTextReader(fs);
                while (reader.Read())
                {
                    try
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.LocalName == "Item")
                            {
                                string id = reader["ID"];
                                string title = reader["title"];
                                string content = reader["content"];
                                if (string.IsNullOrEmpty(content))
                                {
                                    content = "";
                                }
                                //string abstracts = !string.IsNullOrEmpty(content) && content.Length >= 50 ? content.Substring(0, 50) : content;
                                string type = reader["type"];
                                string function = reader["function"];
                                string remark = reader["remark"];
                                string createTime = reader["createTime"];
                                string DB = reader["DB"];

                                RFSerchComponent.Index.IndexString(id, title, content, type, function, remark, createTime, DB);

                                string sqlUpdate = "";
                                if (type == SearchType.Attach)
                                {
                                    sqlUpdate = sqlUpdateAtt;
                                    sb.Append(string.Format(sqlUpdate, content, id)).Append(";");
                                }
                                else if (type == SearchType.News)
                                {
                                    sqlUpdate = sqlUpdateNews;
                                    sb.Append(string.Format(sqlUpdate, id)).Append(";");
                                }
                                else if (type == SearchType.NewsColumn)
                                {
                                    sqlUpdate = sqlUpdateNewsEconomy;
                                    sb.Append(string.Format(sqlUpdate, id)).Append(";");
                                }
                                else if (type == SearchType.InstantMessage)
                                {
                                    sqlUpdate = sqlUpdateSMS;
                                    sb.Append(string.Format(sqlUpdateSMS, id)).Append(";");
                                }
                                count++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        log.WirteLog(ex.Message);
                        continue;
                    }

                }
                reader.Close();
            }

            RFSerchComponent.Index.Close();
            string result = sb.ToString();
            if (result.LastIndexOf(";") > 0)
            {
                return result.Substring(0, result.Length - 1);
            }
            return result;
        }

        /// <summary>
        /// 判断实时库中，文件是否有isXML状态为1（准备创建索引的数据）
        /// </summary>
        public static int PreapareData(EnumServices isXml)
        {
            string strXml = "";
            string xmlPath = "";
            string wordPath = "";
            string dbConnection = "";
            string strNewXml = "";
            string strXMLSMS = "";
            string dbServer;
            switch (isXml)
            {
                case EnumServices.REAL_TIME:
                    {

                        // strXml = "isXML = 2";
                        strXml = "isXML = 1";
                        strNewXml = "IsXML = 1";
                        strXMLSMS = "(isXML IS NULL) OR(isXML = 1)";
                        xmlPath = "RealTimeXML";
                        wordPath = "RealTimeWord";
                        dbConnection = Const.REAL_TIME_DBCONNECTION;
                        dbServer = Const.REAL_TIME_DB;
                    } break;
                case EnumServices.REAL_TIME_REBUILT:
                    {
                        strXml = "isXML = 1 or isXML = 2";
                        strNewXml = "IsXML = 1 or IsXML = 2";
                        strXMLSMS = "(isXML IS NULL) OR(isXML = 1)OR(isXML = 2)";
                        xmlPath = "RealTimeXML";
                        wordPath = "RealTimeWord";
                        dbConnection = Const.REAL_TIME_DBCONNECTION;
                        dbServer = Const.REAL_TIME_DB;
                    } break;
                case EnumServices.FILE_TIME:
                    {
                        strXml = "isXML = 3";
                        strNewXml = "IsXML = 3";
                        strXMLSMS = "isXML = 3";
                        xmlPath = "FileTimeXML";
                        wordPath = "FileTimeWord";
                        dbConnection = Const.FILE_TIME_DBCONNECTION;
                        dbServer = Const.FILE_TIME_DB;
                    } break;
                case EnumServices.FILE_TIME_REBUILT:
                    {
                        strXml = "isXML = 3 or isXML = 4";
                        strNewXml = "IsXML = 3 or IsXML = 4";
                        strXMLSMS = "isXML = 3 or isXML = 4";
                        xmlPath = "FileTimeXML";
                        wordPath = "FileTimeWord";
                        dbConnection = Const.FILE_TIME_DBCONNECTION;
                        dbServer = Const.FILE_TIME_DB;
                    } break;
                default:
                    {
                        strXml = "";
                        xmlPath = "";
                        wordPath = "";
                        dbConnection = "";
                        strNewXml = "";
                        strXMLSMS = "";
                        dbServer = "";
                    }
                    break;
            }
            if (strXml == "")
            {
                log.WirteLog("指定了无效的isXML值：" + isXml.ToString());
                return 0;
            }

            int count = 0;

            //收文发文
            string sqlAttGetDocuments = string.Format("SELECT AttachmentID, AttachmentName, UploadTime, DocumentType, AttachmentContent, FunctionID, Remark "
                     + "FROM P_BT_Attachments "
                     + "WHERE (({0}) and (DocumentType='doc' or DocumentType ='docx')) "
                     + "ORDER BY UploadTime", strXml);
            string sqlGetCodeTable = "SELECT CodeTableID, Code_ID, Code_Type, Code_Desc FROM P_BT_CodeTable";

            //新闻
            string sqlNewsGetDocuments = string.Format("SELECT AnnoNewsID as id, Title as title,Content AS content ,NewsType , CreateTime "
                //   string sqlNewsGetDocuments = string.Format("SELECT AnnoNewsID as id, Title as title,Content AS content , NewsType , CreateTime "
            + "FROM dbo.OA_News_Docs "
                        + "WHERE {0}", strNewXml);

            //栏目新闻
            //string sqlNewsEconomyGetDocuments = string.Format("SELECT E.REC_ID AS id, E.Title AS title, E.[Content] AS content, N.NewsName AS NewsType,  CreateTime "
            //            + "FROM OA_News_Economy AS E INNER JOIN OA_News_Nodes AS N ON E.F_NodeID = N.REC_ID "
            //            + "WHERE {0}", strNewXml);

            string sqlNewsEconomyGetDocuments = string.Format("SELECT E.REC_ID AS id, E.Title AS title, E.[Content] AS content, E.F_NodeID AS NewsType,  CreateTime "
            + "FROM OA_News_Economy AS E "
            + "WHERE {0}", strNewXml);

            //即时消息
            string sqlInstantMessage = string.Format("SELECT SMSID AS id, Title AS title, [Content] AS content, SMSType as NewsType, CreatTime as CreateTime "
            + "FROM OA_WS_InstantMessage_Docs "
            + "WHERE {0}", strXMLSMS);

            try
            {
                //第一步从数据库读取数据，创建XML
                XmlTextWriter xmlWriter;

                string strFilename = ConfigurationManager.AppSettings[xmlPath] + "news.xml";
                Directory.CreateDirectory(ConfigurationManager.AppSettings[xmlPath]);
                //清理旧数据
                DeleteFile(strFilename);

                DataSet dtCodeName = new DbHelper(Const.REAL_TIME_DBCONNECTION).CreateDataSet(CommandType.Text, sqlGetCodeTable);
                DbDataReader dbreader = new DbHelper(dbConnection).ExecuteReader(sqlAttGetDocuments);

                FileStream fs = new FileStream(strFilename, FileMode.OpenOrCreate);

                //ApplicationClass wordApp = new ApplicationClass();
                //object nullobj = System.Reflection.Missing.Value;
                string type = "";

                try
                {
                    xmlWriter = new XmlTextWriter(fs, Encoding.Default);//创建一个xml文档
                    xmlWriter.Formatting = Formatting.Indented;
                    xmlWriter.WriteStartDocument();
                    xmlWriter.WriteStartElement("News");

                    //收文发文
                    while (dbreader.Read())
                    {
                        try
                        {
                            type = SearchType.Attach;//收文发文
                            WriteToXml(xmlWriter, dbreader["AttachmentID"].ToString(), dbreader["AttachmentName"].ToString(), GetWordContent((byte[])dbreader["AttachmentContent"], dbreader["DocumentType"].ToString(), wordPath), type, GetCodeTableID("AttType", dbreader["FunctionID"].ToString(), dtCodeName.Tables[0]), dbreader["Remark"].ToString(), ((DateTime)dbreader["UploadTime"]).ToString("yyyyMMdd"), dbServer);
                            count++;
                        }
                        catch (Exception ex)
                        {
                            log.WirteLog(ex.Message);
                            continue;
                        }
                    }
                    dbreader.Close();
                    //wordApp.Application.Quit(ref nullobj, ref nullobj, ref nullobj);//关闭

                    //新闻
                    dbreader = new DbHelper(dbConnection).ExecuteReader(sqlNewsGetDocuments);
                    while (dbreader.Read())
                    {
                        try
                        {
                            type = SearchType.News;//新闻
                            WriteToXml(xmlWriter, dbreader["id"].ToString(), dbreader["title"].ToString(), dbreader["content"].ToString(), type, dbreader["NewsType"].ToString(), "", ((DateTime)dbreader["CreateTime"]).ToString("yyyyMMdd"), dbServer);
                            count++;
                        }
                        catch (Exception ex)
                        {
                            log.WirteLog(ex.Message);
                            continue;
                        }
                    }
                    dbreader.Close();

                    //栏目新闻
                    dbreader = new DbHelper(dbConnection).ExecuteReader(sqlNewsEconomyGetDocuments);
                    while (dbreader.Read())
                    {
                        try
                        {
                            type = SearchType.NewsColumn;//栏目新闻
                            WriteToXml(xmlWriter, dbreader["id"].ToString(), dbreader["title"].ToString(), dbreader["content"].ToString(), type, dbreader["NewsType"].ToString(), "", ((DateTime)dbreader["CreateTime"]).ToString("yyyyMMdd"), dbServer);
                            count++;
                        }
                        catch (Exception ex)
                        {
                            log.WirteLog(ex.Message);
                            continue;
                        }
                    }

                    //即时消息
                    dbreader = new DbHelper(dbConnection).ExecuteReader(sqlInstantMessage);
                    while (dbreader.Read())
                    {
                        try
                        {
                            type = SearchType.InstantMessage;//即时消息
                            WriteToXml(xmlWriter, dbreader["id"].ToString(), dbreader["title"].ToString(), dbreader["content"].ToString(), type, GetCodeTableID("SMSType", dbreader["NewsType"].ToString(), dtCodeName.Tables[0]), "", ((DateTime)dbreader["CreateTime"]).ToString("yyyyMMdd"), dbServer);
                            count++;
                        }
                        catch (Exception ex)
                        {
                            log.WirteLog(ex.Message);
                            continue;
                        }
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndDocument();
                    xmlWriter.Close();
                }

                catch (Exception ex)
                {
                    log.WirteLog(ex.Message);
                }

                finally
                {
                    if (!dbreader.IsClosed)
                    {
                        dbreader.Close();
                    }

                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                log.WirteLog(ex.Message);
            }

            return count;
        }


        private static void WriteToXml(XmlWriter xmlWriter, string id, string title, string content, string type, string function, string remark, string createtime, string db)
        {

            try
            {
                /*       
               1.	编号ID
               2.	附件名
               3.	附件内容
               4.  类型名称（1：收文发文；2：新闻）
               5.	功能名称
               6.	备注
               7.	创建时间
               8.  所属数据库 1：实时库，2：归档库*/
                xmlWriter.WriteStartElement("Item");
                xmlWriter.WriteAttributeString("ID", id);
                xmlWriter.WriteAttributeString("title", title);
                xmlWriter.WriteAttributeString("content", content);
                xmlWriter.WriteAttributeString("type", type);
                xmlWriter.WriteAttributeString("function", function.ToLower());
                xmlWriter.WriteAttributeString("remark", remark);
                xmlWriter.WriteAttributeString("createTime", createtime);
                xmlWriter.WriteAttributeString("DB", db);
                xmlWriter.WriteEndElement();
            }
            catch
            {
                throw;
            }
        }
        /// <summary>
        /// 获取码表值
        /// </summary>
        /// <param name="codeid"></param>
        /// <param name="dtCodes"></param>
        /// <returns></returns>
        public static string GetCodeTableID(string type, string codeid, System.Data.DataTable dtCodes)
        {
            if (string.IsNullOrEmpty(codeid) || string.IsNullOrEmpty(type))
            {
                return "";
            }

            string result = codeid;
            try
            {
                if (dtCodes != null)
                {
                    DataRow[] rows = dtCodes.Select("Code_ID = '" + codeid + "' and Code_Type = '" + type + "'");
                    if (rows.Length > 0)
                    {
                        return rows[0]["CodeTableID"].ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                log.WirteLog(string.Concat("【GetCodeTableID】message:", ex.Message, "\r\n", "StackTrace：", ex.StackTrace));
            }
            return result;
        }

        /// <summary>
        /// 读取word文档，并转换为字符串
        /// </summary>
        /// <param name="content"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetWordContent(byte[] content, string type, string wordPath)
        {
            string result = "";
            try
            {
                Directory.CreateDirectory(ConfigurationManager.AppSettings[wordPath]);
                string file = ConfigurationManager.AppSettings[wordPath] + "temp." + type;

                using (MemoryStream ms = new MemoryStream(content))
                {
                    using (FileStream fs = new FileStream(file.ToString(), FileMode.OpenOrCreate))
                    {
                        ms.WriteTo(fs);
                        fs.Close();
                    }
                }

                Aspose.Words.Document doc = new Aspose.Words.Document(file);
                result = doc.Document.GetText();
                DeleteFile(file.ToString());
                return result;
            }
            catch (Exception ex)
            {
                log.WirteLog(ex.Message);
                return "";
            }
        }

        public static void DeleteFile(string filepath)
        {
            try
            {
                FileInfo file = new FileInfo(filepath);
                if (file.Exists)
                {
                    file.Delete();
                }
            }
            catch (Exception ex)
            {
                log.WirteLog(ex.Message);
            }
        }
    }
}
